using GroupSix.Application.Dtos;
using GroupSix.Domain.Repositories;
using GroupSix.Domain.Entity.App;
using GroupSix.Domain.common;
using Microsoft.Extensions.Logging;

namespace GroupSix.Application.Services;

/// <summary>
/// 文章服务
/// </summary>
public class ArticleService
{
    private readonly IArticleRepository _articleRepository;
    private readonly ILogger<ArticleService> _logger;

    public ArticleService(
        IArticleRepository articleRepository,
        ILogger<ArticleService> logger)
    {
        _articleRepository = articleRepository;
        _logger = logger;
    }

    /// <summary>
    /// 获取文章列表
    /// </summary>
    /// <param name="query">查询条件</param>
    /// <returns>文章列表</returns>
    public async Task<PageResult<ArticleDto>> GetArticlesAsync(ArticleQueryDto query)
    {
        try
        {
            var result = await _articleRepository.GetArticlesAsync(
                query.Title, 
                query.CategoryId, 
                query.Status, 
                query.AuthorName,
                query.Page, 
                query.PageSize);

            var dtos = result.Items.Select(MapToDto).ToList();

            return new PageResult<ArticleDto>
            {
                Items = dtos,
                TotalCount = result.TotalCount,
                PageIndex = result.PageIndex,
                PageSize = result.PageSize
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取文章列表失败");
            throw;
        }
    }

    /// <summary>
    /// 获取文章分类列表
    /// </summary>
    /// <returns>分类列表</returns>
    public async Task<List<ArticleCategoryDto>> GetCategoriesAsync()
    {
        try
        {
            var categories = await _articleRepository.GetCategoriesAsync();
            return categories.Select(MapToCategoryDto).ToList();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取文章分类列表失败");
            throw;
        }
    }

    /// <summary>
    /// 根据ID获取文章详情
    /// </summary>
    /// <param name="id">文章ID</param>
    /// <returns>文章详情</returns>
    public async Task<ArticleDto?> GetArticleByIdAsync(Guid id)
    {
        try
        {
            var article = await _articleRepository.GetByIdAsync(id);
            return article != null ? MapToDto(article) : null;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取文章详情失败: {Id}", id);
            throw;
        }
    }

    /// <summary>
    /// 创建文章
    /// </summary>
    /// <param name="request">创建请求</param>
    /// <returns>创建结果</returns>
    public async Task<bool> CreateArticleAsync(CreateArticleRequestDto request)
    {
        try
        {
            // 获取分类名称
            string categoryName = "";
            if (request.CategoryId != Guid.Empty)
            {
                var categories = await _articleRepository.GetCategoriesAsync();
                var category = categories.FirstOrDefault(c => c.Id == request.CategoryId);
                categoryName = category?.Name ?? "";
            }

            var article = new GsArticle(
                request.Title,
                request.Content,
                request.CategoryId,
                categoryName,
                request.AuthorId,
                "" // 作者名称将在保存时更新
            )
            {
                Summary = request.Summary,
                Tags = request.Tags,
                Status = request.Status,
                CoverImage = request.CoverImage,
                SeoTitle = request.SeoTitle,
                SeoKeywords = request.SeoKeywords,
                SeoDescription = request.SeoDescription,
                SortWeight = request.SortWeight
            };

            await _articleRepository.CreateAsync(article);

            _logger.LogInformation("文章创建成功: {Title} - {AuthorId}", request.Title, request.AuthorId);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建文章失败: {Title}", request.Title);
            return false;
        }
    }

    /// <summary>
    /// 更新文章
    /// </summary>
    /// <param name="id">文章ID</param>
    /// <param name="request">更新请求</param>
    /// <returns>更新结果</returns>
    public async Task<bool> UpdateArticleAsync(Guid id, UpdateArticleRequestDto request)
    {
        try
        {
            var article = await _articleRepository.GetByIdAsync(id);
            if (article == null)
            {
                _logger.LogWarning("文章不存在: {Id}", id);
                return false;
            }

            // 获取分类名称
            string categoryName = "";
            if (request.CategoryId != Guid.Empty)
            {
                var categories = await _articleRepository.GetCategoriesAsync();
                var category = categories.FirstOrDefault(c => c.Id == request.CategoryId);
                categoryName = category?.Name ?? "";
            }

            article.UpdateBasicInfo(
                request.Title,
                request.Content,
                request.Summary,
                request.CategoryId,
                categoryName,
                request.Tags
            );

            article.UpdateSeoInfo(
                request.SeoTitle,
                request.SeoKeywords,
                request.SeoDescription
            );

            article.Status = request.Status;
            article.CoverImage = request.CoverImage;
            article.UpdateSortWeight(request.SortWeight);

            await _articleRepository.UpdateAsync(article);

            _logger.LogInformation("文章更新成功: {Id} - {Title}", id, request.Title);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "更新文章失败: {Id}", id);
            return false;
        }
    }

    /// <summary>
    /// 删除文章
    /// </summary>
    /// <param name="id">文章ID</param>
    /// <returns>删除结果</returns>
    public async Task<bool> DeleteArticleAsync(Guid id)
    {
        try
        {
            var article = await _articleRepository.GetByIdAsync(id);
            if (article == null)
            {
                _logger.LogWarning("文章不存在: {Id}", id);
                return false;
            }

            await _articleRepository.DeleteAsync(id);

            _logger.LogInformation("文章删除成功: {Id} - {Title}", id, article.Title);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "删除文章失败: {Id}", id);
            return false;
        }
    }

    /// <summary>
    /// 批量删除文章
    /// </summary>
    /// <param name="ids">文章ID列表</param>
    /// <returns>删除数量</returns>
    public async Task<int> BatchDeleteArticlesAsync(List<Guid> ids)
    {
        try
        {
            var deletedCount = 0;
            foreach (var id in ids)
            {
                if (await DeleteArticleAsync(id))
                {
                    deletedCount++;
                }
            }

            _logger.LogInformation("批量删除文章完成: {DeletedCount}/{TotalCount}", deletedCount, ids.Count);
            return deletedCount;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "批量删除文章失败");
            throw;
        }
    }

    /// <summary>
    /// 发布文章
    /// </summary>
    /// <param name="id">文章ID</param>
    /// <returns>发布结果</returns>
    public async Task<bool> PublishArticleAsync(Guid id)
    {
        try
        {
            var article = await _articleRepository.GetByIdAsync(id);
            if (article == null)
            {
                _logger.LogWarning("文章不存在: {Id}", id);
                return false;
            }

            article.Publish();
            await _articleRepository.UpdateAsync(article);

            _logger.LogInformation("文章发布成功: {Id} - {Title}", id, article.Title);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "发布文章失败: {Id}", id);
            return false;
        }
    }

    /// <summary>
    /// 下线文章
    /// </summary>
    /// <param name="id">文章ID</param>
    /// <returns>下线结果</returns>
    public async Task<bool> OfflineArticleAsync(Guid id)
    {
        try
        {
            var article = await _articleRepository.GetByIdAsync(id);
            if (article == null)
            {
                _logger.LogWarning("文章不存在: {Id}", id);
                return false;
            }

            article.Offline();
            await _articleRepository.UpdateAsync(article);

            _logger.LogInformation("文章下线成功: {Id} - {Title}", id, article.Title);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "下线文章失败: {Id}", id);
            return false;
        }
    }

    /// <summary>
    /// 设置文章置顶状态
    /// </summary>
    /// <param name="id">文章ID</param>
    /// <param name="isTop">是否置顶</param>
    /// <returns>设置结果</returns>
    public async Task<bool> SetArticleTopStatusAsync(Guid id, bool isTop)
    {
        try
        {
            var article = await _articleRepository.GetByIdAsync(id);
            if (article == null)
            {
                _logger.LogWarning("文章不存在: {Id}", id);
                return false;
            }

            article.SetTopStatus(isTop);
            await _articleRepository.UpdateAsync(article);

            _logger.LogInformation("文章置顶状态设置成功: {Id} - {IsTop}", id, isTop);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "设置文章置顶状态失败: {Id}", id);
            return false;
        }
    }

    /// <summary>
    /// 设置文章推荐状态
    /// </summary>
    /// <param name="id">文章ID</param>
    /// <param name="isRecommend">是否推荐</param>
    /// <returns>设置结果</returns>
    public async Task<bool> SetArticleRecommendStatusAsync(Guid id, bool isRecommend)
    {
        try
        {
            var article = await _articleRepository.GetByIdAsync(id);
            if (article == null)
            {
                _logger.LogWarning("文章不存在: {Id}", id);
                return false;
            }

            article.SetRecommendStatus(isRecommend);
            await _articleRepository.UpdateAsync(article);

            _logger.LogInformation("文章推荐状态设置成功: {Id} - {IsRecommend}", id, isRecommend);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "设置文章推荐状态失败: {Id}", id);
            return false;
        }
    }

    /// <summary>
    /// 获取文章统计信息
    /// </summary>
    /// <returns>统计信息</returns>
    public Task<ArticleStatisticsDto> GetArticleStatisticsAsync()
    {
        try
        {
            // 这里需要实现具体的统计逻辑
            // 暂时返回模拟数据
            var statistics = new ArticleStatisticsDto
            {
                TotalArticles = 156,
                PublishedArticles = 89,
                DraftArticles = 45,
                OfflineArticles = 22,
                TotalViews = 12580,
                TotalLikes = 2340,
                TotalComments = 890,
                TodayNewArticles = 5,
                TodayViews = 320,
                TopArticles = 8,
                RecommendArticles = 12
            };

            _logger.LogInformation("获取文章统计信息成功");
            return Task.FromResult(statistics);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取文章统计信息失败");
            throw;
        }
    }

    /// <summary>
    /// 增加文章阅读量
    /// </summary>
    /// <param name="id">文章ID</param>
    /// <returns>操作结果</returns>
    public async Task<bool> IncrementArticleViewCountAsync(Guid id)
    {
        try
        {
            var article = await _articleRepository.GetByIdAsync(id);
            if (article == null)
            {
                _logger.LogWarning("文章不存在: {Id}", id);
                return false;
            }

            article.IncrementViewCount();
            await _articleRepository.UpdateAsync(article);

            _logger.LogInformation("文章阅读量增加成功: {Id} - {ViewCount}", id, article.ViewCount);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "增加文章阅读量失败: {Id}", id);
            return false;
        }
    }

    /// <summary>
    /// 点赞文章
    /// </summary>
    /// <param name="id">文章ID</param>
    /// <returns>操作结果</returns>
    public async Task<bool> LikeArticleAsync(Guid id)
    {
        try
        {
            var article = await _articleRepository.GetByIdAsync(id);
            if (article == null)
            {
                _logger.LogWarning("文章不存在: {Id}", id);
                return false;
            }

            article.IncrementLikeCount();
            await _articleRepository.UpdateAsync(article);

            _logger.LogInformation("文章点赞成功: {Id} - {LikeCount}", id, article.LikeCount);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "文章点赞失败: {Id}", id);
            return false;
        }
    }

    /// <summary>
    /// 取消点赞文章
    /// </summary>
    /// <param name="id">文章ID</param>
    /// <returns>操作结果</returns>
    public async Task<bool> UnlikeArticleAsync(Guid id)
    {
        try
        {
            var article = await _articleRepository.GetByIdAsync(id);
            if (article == null)
            {
                _logger.LogWarning("文章不存在: {Id}", id);
                return false;
            }

            article.DecrementLikeCount();
            await _articleRepository.UpdateAsync(article);

            _logger.LogInformation("取消文章点赞成功: {Id} - {LikeCount}", id, article.LikeCount);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "取消文章点赞失败: {Id}", id);
            return false;
        }
    }

    /// <summary>
    /// 映射到DTO
    /// </summary>
    private ArticleDto MapToDto(GsArticle article)
    {
        return new ArticleDto
        {
            Id = article.Id,
            Title = article.Title,
            Content = article.Content,
            Summary = article.Summary,
            CategoryId = article.CategoryId,
            CategoryName = article.CategoryName,
            Tags = article.Tags,
            Status = article.Status,
            AuthorId = article.AuthorId,
            AuthorName = article.AuthorName,
            CoverImage = article.CoverImage,
            ViewCount = article.ViewCount,
            LikeCount = article.LikeCount,
            CommentCount = article.CommentCount,
            PublishedAt = article.PublishedAt,
            SeoTitle = article.SeoTitle,
            SeoKeywords = article.SeoKeywords,
            SeoDescription = article.SeoDescription,
            IsTop = article.IsTop,
            IsRecommend = article.IsRecommend,
            SortWeight = article.SortWeight,
            CreatedAt = article.CreatedAt,
            UpdatedAt = article.UpdatedAt
        };
    }

    private ArticleCategoryDto MapToCategoryDto(GsArticleCategory category)
    {
        return new ArticleCategoryDto
        {
            Id = category.Id,
            Name = category.Name,
            Description = category.Description,
            ParentId = category.ParentId,
            Level = category.Level,
            SortOrder = category.SortOrder,
            CreatedAt = category.CreatedAt,
            UpdatedAt = category.UpdatedAt
        };
    }
} 